package com.nce;

import java.util.HashMap;

import com.nce.converter.FileWriter;
import com.nce.converter.Format;
import com.nce.converter.Preprocessor;
import com.nce.converter.Transcoder;

/**
 * @author Domenico
 * This class provides an easy way to covert multimedia streams, maintaining the sync.
 * Conversions could involve extraction from rtp communications, transcoding and resampling.
 * <br>The conversion process is divided into 3 main steps:
 * <ul><li>pre-processing the input file
 * <li>transcoding the streams 
 * <li>writing the transcoded stream in a file
 * </ul>
 * 
 * @see Preprocessor
 * @see Transcoder
 * @see FileWriter
 */
public class Converter {

	private Preprocessor preprocessor = null;
	private Transcoder transcoder = null;
	private FileWriter fileWriter = null;
	
	private String fileNameInput = null;
	private String fileNameOutput = null;
	private Format inputFormat = null;
	private Format outputFormat =  null;
	
	
	/**
	 * Constructor.
	 * @param inputFormat description of the input file
	 * @param fileNameInput name of the file containing the streams to convert
	 * @param outputFormat description of the output file
	 * @param fileNameOutput name of the file where to save the converted streams
	 */
	public Converter (Format inputFormat, String fileNameInput, Format outputFormat, String fileNameOutput)
	{
		this.inputFormat = inputFormat;
		this.fileNameInput = fileNameInput;
		this.outputFormat = outputFormat;
		this.fileNameOutput = fileNameOutput;
	}
	
	
	/**
	 * Initializes the converter.
	 * @return true if inited, false if errors in itialization occurred
	 */
	public boolean init()
	{
		HashMap<String, Object> configMap = null;
		preprocessor = new com.nce.converter.pcap.Preprocessor();
		preprocessor.init(inputFormat, fileNameInput);
		if (!preprocessor.preprocess())
		{
			return false;
		}
		configMap = preprocessor.getInfo();
		if (configMap == null)
		{
			return false;
		}
		configMap.put("output.file.format", outputFormat);
		configMap.put("output.file.name", fileNameOutput);
		transcoder = new com.nce.converter.audio.Transcoder();
		if (!transcoder.init(configMap))
		{
			return false;
		}
		fileWriter = new com.nce.converter.audio.WaveFileWriter();
		if (!fileWriter.init(configMap))
		{
			return false;
		}
		fileWriter.connectToTranscoder(transcoder);
		return true;
	}
	
	
	/**
	 * Performs the conversion of the streams. 
	 */
	public void convert()
	{
		transcoder.startTranscoding();
		fileWriter.startWriting();
		transcoder.waitForStop();
		fileWriter.waitForStop();
//		try {
//			((Thread)fileWriter).join();
//		} catch (InterruptedException ex)
//		{
//			ex.printStackTrace();
//		}
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String path = null;
		try{
	      path = System.getProperty("user.dir");
	      path += java.io.File.separator;
	      //System.out.print("Executing at =>"+executionPath.replace("\\", "/"));
		}catch (Exception e){
	      System.out.println("Exception caught ="+e.getMessage());
	      return;
		}
		String pcapFile = path + "rtp_ciscophone_2participants.pcap";
		String waveFile = path + "temp1.wav";
		Format pcapFormat = new Format(Format.FILE_PCAP_RTP);
		Format waveFormat = new Format(Format.FILE_WAVE_PCM);
		Converter converter = new Converter(pcapFormat, pcapFile, waveFormat, waveFile);
		if (converter.init())
		{
			converter.convert();
			//new WavePlayerTest(waveFile).start();
			//String waveMulti = path + "temp.wav";
			//WavePlayerWindow window = new WavePlayerWindow(waveMulti);
		} else
		{
			System.err.println("couldn't init the converter");
		}
	}

}
